#include "CoreThread.h"
#include <iostream>
#include "ThreadSafePrinter.h"
#include "TimeInterval.h"

HTHREADPOOL_NAMESPACE_BEGIN

    CoreThread::CoreThread(
        int index, AtomicQueue<Task>* poolTaskQueue, std::vector<std::unique_ptr<CoreThread>>* poolThreads)
    : ThreadPoolObject(ThreadType::kCore, poolTaskQueue)
    , m_index(index)
    , m_pool_threads(poolThreads)
    {
    }

    CoreThread::~CoreThread()
    {
        exit();
    }

    void CoreThread::exit() {quit();}

    void CoreThread::run()
    {
        while(true) {
            {
                std::unique_lock<std::mutex> lock(m_mutex);
                m_cv.wait(lock, [this] {
                    return m_state.load() == ThreadState::kRunning || m_state.load() == ThreadState::kTerminated;
                });

                if(m_state.load() == ThreadState::kTerminated) {
                    break;
                }
            }

            if(!m_isBatchExecution.load()) {
                while(true) {
                    if(m_state.load() == ThreadState::kTerminated) {
                        break;
                    }
                    excuteTask();
                }
            } else {
                while(true) {
                    if(m_state.load() == ThreadState::kTerminated) {
                        break;
                    }
                    excuteTasks();
                }
            }
        }
    }

    void CoreThread::excuteTask()
    {
        Task task;
        if(popTask(task) || popPoolTask(task) || stealTask(task)) {
            runTask(task);
        } else {
            TimeInterval      timeInterval;
            timeInterval.start();
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
            timeInterval.end();
            std::this_thread::yield();
        }
    }

    void CoreThread::excuteTasks()
    {
        TaskArr tasks;
        //优先从本地拿,其次在去线程池中拿,如果线程池中没有,则去隔壁拿
        if(popTask(tasks) || popPoolTask(tasks) || stealTask(tasks)) {
            // 尝试从主线程中获取/盗取批量task，如果成功，则依次执行
            runTasks(tasks);
        } else {
            TimeInterval      timeInterval;
            timeInterval.start();
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
            timeInterval.end();
            std::this_thread::yield();
        }
    }
    void CoreThread::commit(Task && task) { m_loaclWorkQueue.push(std::move(task)); }
    bool CoreThread::popTask(TaskRef task) { return m_loaclWorkQueue.tryPop(task); }
    bool CoreThread::popTask(TaskArrRef tasks)
    {
        return false;
        // return m_work_stealing_queue.tryPop(tasks, m_config->max_local_batch_size_);
    }
    bool CoreThread::stealTask(TaskArrRef tasks) { return false; }
    bool CoreThread::stealTask(TaskRef tasks) { return false; }

HTHREADPOOL_NAMESPACE_END
